<!DOCTYPE html>
<html lang="en">
<head profile="http://www.w3.org/2006/03/hcard">
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  <title>CSS Pagination Templates Module Level 3</title>
  <link rel="stylesheet" type="text/css" href="../shared/style/default.css">
  <!--link rel="stylesheet" type="text/css" href="https://www.w3.org/StyleSheets/TR/W3C-ED.css"-->
  <link rel="stylesheet" type="text/css" href="https://www.w3.org/StyleSheets/TR/w3c-unofficial.css">



  <style type="text/css">
    body {
        counter-reset: issue;
    }
  </style>
        <link rel="stylesheet" type="text/css"
         href="../shared/style/issues.css">

       <link id="st" href="../shared/style/alternate-spec-style.css" rel="stylesheet"
              type="text/css" title="alternate spec style">
</head>

<body><div class="head">
<!--logo-->

<h1>CSS Pagination Templates Module Level 3</h1>

<h2 class="no-num no-toc">[LONGSTATUS] [DATE]</h2>

  <dl>
    <dt>This version:
    <!--<dd><a href="[VERSION]">[VERSION]</a>-->
    <dd><a href="//drafts.csswg.org/css3-page-template/">https://drafts.csswg.org/css3-page-template/</a>

    <dt>Latest version:
    <!--<dd><a href="[LATEST]">[LATEST]</a>-->
    <dd><a href="//www.w3.org/TR/css3-page-template/">https://www.w3.org/TR/css3-page-template/</a>

    <dt>Editor's draft:
    <dd><a href="//drafts.csswg.org/css3-page-template/">https://drafts.csswg.org/css3-page-template/</a>
  <!--
    <dt>Previous version:
    <dd><a href="http://www.w3.org/PreviousVersionURI">
      http://www.w3.org/PreviousVersionURI</a>
  -->
  <dt>Feedback:</dt>
    <dd><a href="mailto:www-style@w3.org?subject=%5Bcss-page-template%5D%20feedback"
         >www-style@w3.org</a>
         with subject line &ldquo;<kbd>[css-page-template]
         <var>&hellip; message topic &hellip;</var></kbd>&rdquo;
         (<a rel="discussion" href="http://lists.w3.org/Archives/Public/www-style/"
           >archives</a>)
    <dt>Editors:
    <dd class="vcard"><span class="fn">Alan Stearns</span>,
      <span class="org">Adobe Systems, Inc.</span>,
      <span class="email">stearns@adobe.com</span>
  </dl>

<!--copyright-->

<hr title="Separator for header">
</div>

<details class=annoying-warning open>
  <summary>Not Ready For Implementation</summary>
  <p>
    This spec is not yet ready for implementation.
    It exists in this repository to record the ideas and promote discussion.

  <p>
    Before attempting to implement this spec,
    please contact the CSSWG at www-style@w3.org.
</details>

<h2 class="no-num no-toc" id="abstract">Abstract</h2>

  <p>The Pagination Templates module describes templates that generate boxes in CSS to display content in a paginated view. These templates define a page  containing one or more boxes with content assignments. As content overflows additional pages are generated using template selection rules until all of the content is displayed.

<h2 class="no-num no-toc" id="status">Status of this document</h2>

<!--begin-status-->
  <p><strong>This document is an unofficial Editor's Draft. It is provided for discussion only and may change at any moment. It has not yet been adopted by the Working Group, and should not be considered to be part of CSS.</strong>

  <p>The archived public mailing list www-style@w3.org is preferred for discussion of this specification. When sending e-mail, please put the text "css3-page-template" in the subject, preferably like this: "[css3-page-template] …summary of comment…"
<!--end-status-->
  <p>The following features are at risk: none

<nav id="toc">
<h2 class="no-num no-toc" id="contents">Table of contents</h2>

<!--toc-->
</nav>

<h2 id="intro">Introduction</h2>

  <p><em>This section is not normative.</em>

  <p>This module describes how to define pagination templates in CSS. In CSS 2.1 content displayed on-screen is assumed to be a single continuous canvas. Pagination templates provide a mechanism for a 'paginated' experience that applies to on-screen presentation as well as printed media. Pagination templates define boxes in CSS where content is displayed as the user moves from page to page on screen or prints the document. When content is laid out using pagination templates, pages are generated as needed to accommodate all the content.

  <div class="issue-marker wrapper">
  <div class="issue-marker"><div class="issue-details">The draft as it stands requires pagination to present the repeated template layouts. Other methods of repeating template layouts to accommodate content might be specified, but the draft would need to be reviewed to remove all reliances on paged displays.</div></div>
  <div class="issue-marker"><div class="issue-details">The terms 'template' and 'page' are overloaded in CSS, but they are the words that most clearly describe the concept. Some alternates for the main @ rule: template, page-template, view-template, page-master, master-template, master. Other suggestions are welcome, but only if they are more helpful than onelook.com (which suggested "Captain Submarine").</div></div>
  <div class="issue-marker"><div class="issue-details">This specification may be the best place to define "continued here" or "continued on page x" generated content, since this spec defines ways to skip pages (that basic pagination may not).</div></div>
  </div>

  <p>Pagination templates consist of anonymous boxes called slots created by CSS to contain content. Layouts that use pagination templates mainly determine the size of these slots from the template definition instead of the size of their content. When content does not fit into a template slot, additional pages are created with more slots to contain the overflow content.

  <p>Multiple pagination templates can be defined for a given document. A paginated element can use a single template or select from a set of templates each time a new page needs to be generated. Which template is used for a given page can be defined by a selector or by choosing a template based on available content. Elements can further constrain the applicable template set by listing a subset of templates that apply.


<h3 id="placement">Module Interactions</h3>

  <p>This module uses named flows and region chains defined in [[CSS3-REGIONS]].
  <p>This module uses the overflow-style property from [[CSS3GCPM]].
  <p>Some examples use positioning from [[CSS3GRID]].

<h2 id="templates-and-slots">Pagination Templates and Slots</h2>

  <p>An @template rule defines and names a pagination template. Pagination templates contain one or more slots to display content. These slots create boxes for each page generated from a pagination template. An element can use pagination templates if its 'overflow-style' property is set to any of the paged-* values defined in css3-gcpm. If a document defines no pagination templates, then there is an implicit pagination template with a single slot containing the paginated element's contents.

  <div class="issue-marker"><div class="issue-details">Instead of a dependency on GCPM, this spec could define what happens with a paginated view, without specifying how the paginated view comes into existence. What happens when you apply 'overflow-style:paged-x' to an iframe or region?</div></div>

  <p>The box created from an @template rule defaults to the size of the paginated element's box.

  <p>A slot is an anonymous box in a pagination template where content can be placed. In an @template rule @slot rules create slots. The order of @slot rules determines the order of the boxes in the pagination template. @slot rules can define a name for the slot.

  <p>Slots default to displaying the content of the paginated element. Slots can instead contain generated content assigned with the content property. Slots can also be assigned content from named flows.

  <div class='example'>
    <p>An @template rule that creates header and footer slots around the paginated element's content
    <pre>
    @template paged-display {
      @slot header { content: "header string"; }
      @slot content { }
      @slot footer { content: "footer string"; }
    }
    </pre>
  </div>

  <p>If any slot in a particular page has overflow content, a new page is created with a new set of slots to receive the overflow content. Slots with the same named flow assignment form a region chain (within a pagination template and/or across pages created from pagination templates). When a new page is created a slot that has been assigned element content or content from a named flow may not have any content left to render. In this case the slot for the exhausted content source is not instantiated.

  <div class="issue-marker"><div class="issue-details">If there is more than one slot with no 'content' or 'flow-from' assignment, does the element's content use all of these slots like a region chain, or is only the last unassigned slot used for content?</div></div>

  <div class='example'>
    <p>The simplest example takes all of the content in the document and flows it into a single pagination template with a single slot. This template will display a viewport's worth of content at a time, and will create a new slot on a new page each time content overflows.

    <p>The three examples below are equivalent, but merely illustrate how content from the element can be assigned to pagination template slots. Actual use of templates would either define more slots or assign content differently than the default.

    <pre class='separate-pre'>
    body { overflow-style: paged-x; }</pre>
    <pre class='separate-pre'>
    body { overflow-style: paged-x; }
    @template paged-display {
      @slot content { }
    }</pre>
    <pre class='separate-pre'>
    body { overflow-style: paged-x; }
    body > * { flow-into: body-flow; }
    @template paged-display {
      @slot content { flow-from: body-flow; }
    }</pre>
  </div>

  <div class="issue-marker"><div class="issue-details">
    <p>@slot rules are a first pass at defining CSS-created boxes. Other means of creating and addressing pseudo-element slots have been discussed on www-style. If @slot rules or pseudo-elements are used to create template boxes, then OM for pseudo-elements must be defined (scripting and events working with paginated content is a valid use case).
    <p>One argument against using pseudo-elements to create templates is that this is defining structure in CSS. If nested slots are required, then we're on a slippery slope towards re-inventing HTML inside of CSS.
    <p>An alternative could use Shadow DOM to define the boxes. This gives us structure and OM, but would need a declarative method of mapping content to elements. One suggestion was to use @slot rules in a flat list for the simple case, but start to rely on Shadow DOM for more complicated cases. If this route is taken, then @slot rules probably aren't required, as Shadow DOM can also handle the flat list case.</div></div>

  <p>Pagination templates can use declarations to determine the layout method for slots. @slot rules can use sizing and positioning declarations.

  <div class='example'>
    <p>A pagination template could contain two side-by-side slots that paginate two separate articles. Side-by-side translations are often laid out this way. This example fills the left side of the paged view with content from an English article and the right side with content from a French article. New pages and slots are created until the content from both articles is exhausted. If one article is longer than the other then in this simple example template the longer article will continue taking up just its half of the page.
    <p>
    <img src="images/side-by-side-1.png" width="120" alt="side-by-side flows on a page">
    <span style="font-size:50px">…</span>
    <img src="images/side-by-side-2.png" width="120" alt="side-by-side flows with the left ending">
    <img src="images/only-one-side-3.png" width="120" alt="only the right flow">
    <span style="font-size:50px">…</span>
    <pre>
    body { overflow-style: paged-x; }
    .english { flow-into: english-flow; }
    .french { flow-into: french-flow; }
    @template side-by-side {
      @slot left {
        flow-from: english-flow;
        width: 40%;
        height: 90%;
        padding: 5%;
        float: left;
      }
      @slot right {
        flow-from: french-flow;
        width: 40%;
        height: 90%;
        padding: 5%
        float: right;
      }
    }
    &lt;body&gt;
      &lt;article class='english'&gt;...content...&lt;/article&gt;
      &lt;article class='french'&gt;...contenu...&lt;/article&gt;
    &lt;/body&gt;
    </pre>
  </div>

  <div class='example'>
    <p>The example above could position the slots using grid layout rather than floats. In this simple example the longer article will take up the entire page once the shorter article is exhausted.
    <p>
    <img src="images/side-by-side-1.png" width="120" alt="side-by-side flows on a page">
    <span style="font-size:50px">…</span>
    <img src="images/side-by-side-2.png" width="120" alt="side-by-side flows with the left ending">
    <img src="images/whole-page.png" width="120" alt="the right flow takes up the whole page">
    <span style="font-size:50px">…</span>
    <pre>
    body { overflow-style: paged-x; }
    .english { flow-into: english-flow; }
    .french { flow-into: french-flow; }
    @template side-by-side {
      display: grid;
      grid-columns: 1fr 1fr;
      @slot left {
        flow-from: english-flow;
        padding: 5%;
        grid-column: 1;
      }
      @slot right {
        flow-from: french-flow;
        padding: 5%
        grid-column: 2;
      }
    }
    &lt;body&gt;
      &lt;article class='english'&gt;...content...&lt;/article&gt;
      &lt;article class='french'&gt;...contenu...&lt;/article&gt;
    &lt;/body&gt;
    </pre>
  </div>

<h2 id="conditional-templates">Template Selection</h2>

  <p>Multiple templates can be defined for a single document. An element that uses pagination templates either selects a template from the entire document set or a subset defined by the 'template-set' property. Each page view created uses a single template. This template can be chosen from the applicable set using a selector, by matching content to display using the 'required-flow' or 'available-content' declarations, or just taking the last template found.

  <div class="issue-marker"><div class="issue-details">The following section describes selecting templates with several mechanisms (selectors and declarations, and presumably @template rules could be scoped by media queries). An alternative could be to define all selection mechanisms like a media query, where all of the selection mechanisms are outside the declaration block. Attempting to define template rejection rather than selection might also prove fruitful.</div></div>

  <div class='example'>
    <p>In this example the divs are paginated using the last template found from the set of templates that apply to the div. The first div uses template three, the second div uses template two, and the third div uses template one.

    <pre>
    div { overflow-style: paged-x; }
    .either-one-or-two { template-set: one two; }
    .only-one { template-set: one; }

    @template one { ... }
    @template two { ... }
    @template three { ... }

    &lt;div class='any-template'&gt; ... &lt;/div&gt;
    &lt;div class='either-one-or-two'&gt; ... &lt;/div&gt;
    &lt;div class='only-one'&gt; ... &lt;/div&gt;
    </pre>
  </div>

<h3 id='ordered-templates'>Selecting Templates by Page Order</h3>

  <p>Selectors such as :first can be used on a pagination template to define a separate template for pages that match the selector.

  <div class="issue-marker wrapper">
  <div class="issue-marker"><div class="issue-details">Should :left and :right be allowed with a way of displaying more than one page at a time in a viewport? Should :nth(x) selectors be allowed?</div></div>

  <div class="issue-marker"><div class="issue-details">Describe how @template rules cascade with names and selectors (or how they do not cascade, if that's preferable).</div></div>
  </div>

  <div class='example'>
    <p>Any of the side-by-side two-article examples from the previous section could have an @template :first {} rule that defined a fancy layout for the first page.
    <pre>
    @template side-by-side:first {
      @slot left {
        //fancy styling
        flow-from: article1;
      }
      @slot right {
        //fancy styling
        flow-from: article2;
      }
    }
    </pre>
  </div>

  <div class="issue-marker wrapper">

  <div class="issue-marker"><div class="issue-details">define "fancy."</div></div>

  <div class="issue-marker"><div class="issue-details">Depending on how template selection is defined, there will likely be scenarios where degenerate template sets can either fail to display all of the content or result in an infinite loop of page generation. This first draft falls into the latter category (make a :first template with a slot that overflows, but fail to include an assignment for that slot's content in all other templates), so this will need to be addressed with more selection rules.</div></div>
  </div>

<h3 id='selection-from-required-flows'>Selecting Templates from Required Flows</h3>

  <p>The 'required-flow' property can be used in a pagination template to list named flows that must still have content in order for the template to be used. If more than one template has a 'required-flow' value that matches the remaining flow content, the last template that matches will be used.

  <div class='example'>
    <p>"Continued on" layout.
    <p>These pagination templates will display an initial page with the beginning of both the 'lead-story' flow and a 'related-article' flow. If the lead story has more content than will fit on that first page, the next page(s) will show only content from that lead story. When the content from the lead story is exhausted, then pages will follow with content from the related article.
    <p>
    <img src="images/side-by-side-1.png" width="120" alt="side-by-side flows on a page">
    <img src="images/first-article-columns.png" width="120" alt="columns continuing just the first flow">
    <span style="font-size:50px">…</span>
    <img src="images/first-article-end.png" width="120" alt="columns ending the first flow">
    <img src="images/second-article-columns.png" width="120" alt="columns continuing the second flow">
    <span style="font-size:50px">…</span>
    <pre>
    body { overflow-style: paged-x; }
    .lead-story { flow-into: lead-flow; }
    .related-article { flow-into: related-flow; }
    @template related {
      required-flow: related-flow;
      @slot content {
        flow-from: related-flow;
        column-width: 20em;
      }
    }
    @template lead {
      required-flow: lead-flow;
      @slot content {
        flow-from: lead-flow;
        column-width: 20em;
      }
    }
    @template continued-on:first {
      @slot lead {
        flow-from: lead-flow;
        width: 40%;
        height: 90%;
        padding: 5%;
        float: left;
      }
      @slot related {
        flow-from: related-flow;
        width: 40%;
        height: 90%;
        padding: 5%
        float: left;
      }
    }
    &lt;body&gt;
      &lt;article class='lead-story'&gt;...content...&lt;/article&gt;
      &lt;article class='related-article'&gt;...content...&lt;/article&gt;
    &lt;/body&gt;
    </pre>
  </div>

<h3 id='selection-from-available-content'>Selecting Templates from Available Content</h3>

  <p>Pagination templates can be selected based on the order of content in the DOM tree. Content may be split out into one or more named flows, but the original order can be discovered in the DOM and used for template selection.

  <p>Pagination templates have a 'primary' content flow. The primary flow for a pagination template is usually the content of the paginated element. If no slot in the template displays the element contents, then the primary flow of the pagination template is the first named flow in its required-flow declaration.

  <p>When selecting the pagination template for the next page, the primary flow in the original markup can be scanned to determine whether any out-of-flow content in other named flows was originally related to the next page of primary flow. If this is the case, then those named flows have 'available' content for the purpose of selecting an appropriate template that can display this content.

  <p>Pagination templates can have an 'available-content' declaration listing the named flows that must have available content for the template to be selected. Templates with more 'available-content' flow matches take precedence over fewer or no 'available-content' flow matches. If a template with an 'available-content' declaration is chosen, only the available content in those flows is displayed in the slots associated with those flows.

  <div class='example'>
    <p>Clarification example (not meant to be a valid use case)
    <p>Consider an article element that contains images scattered throughout. Assign the images to a flow named 'images' and the rest of the article to a flow named 'text'. Then define two pagination templates - one that has slots only for the 'text' flow, and another that has slots for both the 'text' and 'images' flows. Both templates require the 'text' flow, but the second template also requires the 'images' flow and has an 'available-content' declaration listing the 'images' flow. Each time a page is laid out, the original article element is scanned to see whether an image element is in the next page's worth of content (determined by some DOM-tree-scanning heuristic – not layout). If so, then that content from the 'images' flow is available for the purpose of selecting a template.
  </div>

  <div class='example'>
    <p>Motivational example (meant as a use case)
    <p>Assume you have an article that contains both pull quotes and images. If only images <em>or</em> pull quotes would occur on a page, position those elements in the center right of the template. But if both images <em>and</em> pull quotes would appear, position the images in the top left and the pull quotes in the bottom right.
    <div class="issue-marker"><div class="issue-details">code this example</div></div>
  </div>

<h2 id="cssom">CSS Object Model</h2>

  <div class="issue-marker"><div class="issue-details">There should be extensive OM defined to access pages and slots. What page is being displayed should be available. Pages and slots should accept event handlers. Anchors should navigate to the appropriate page (as should search). What content fits in each slot and page should be determinable. Lots to fill out here.</div></div>

  <div class='example'>
    <p>Motivational example
    <p>Given the side-by-side paginated template for French and English, allow the user to click and drag the French text from the right to the left to switch sides for both flows.
  </div>

<h2 id="conformance">Conformance</h2>

<h2 class="no-num" id="acknowledgments">Acknowledgments</h2>

    <p>The editor is grateful to the CSS working group for their feedback and help with the genesis of this specification.</p>

    <p>In addition, the editor would like to thank the following individuals for their contributions, either during the conception of CSS Pagination Templates or during its development and specification review process:</p>
    <ul>
        <li>Rossen Atanassov</li>
        <li>Tab Atkins</li>
        <li>Razvan Caliman</li>
        <li>Alexandru Chiculita</li>
        <li>Sylvain Galineau</li>
        <li>Vincent Hardy</li>
        <li>David Hyatt</li>
        <li>Brad Kemper</li>
        <li>Håkon Wium Lie</li>
        <li>Alex Mogilevsky</li>
        <li>Christoph Päper</li>
        <li>Peter Sorotokin</li>
        <li>Stephen Zilles</li>
    </ul>

<h2 class="no-num" id="references">References</h2>


<h3 class="no-num" id="normative-references">Normative references</h3>
<!--normative-->

<h3 class="no-num" id="other-references">Other references</h3>
<!--informative-->

<h2 class="no-num" id="index">Index</h2>
<!--index-->

    <!-- template markup for issues pulled from Bugzilla -->
    <!--
    <script type="text/template" id="issue-template">
<div class="issue-marker" style="display:none" data-bug_id="{{bug_id}}" data-bug_status="{{bug_status}}">
    <a href="https://www.w3.org/Bugs/Public/show_bug.cgi?id={{bug_id}}">Bug-{{bug_id}}</a>
    <div class="issue-details">
        <p class="short-desc">{{short_desc}}</p>
    </div>
</div>
    </script>

    <script type="text/javascript" src="../shared/scripts/BugzillaTrackerUtil.js"></script>
    <script type="text/javascript" src="../shared/scripts/BugzillaTracker.js"></script>
    <script type="text/javascript">
checkSpecificationIssues('CSS', 'Page Template');
    </script>


    <div id="issue-manager">
        <h2>Issue manager</h2>
        <form action="#">
            <label>
                <input type="radio" name="issue-filter" value="all" checked/>
                All issues
            </label>
            <label>
                <input type="radio" name="issue-filter" value="updated" />
                Updated issues
            </label>
            <label>
                <input type="radio" name="issue-filter" value="new" />
                New issues
            </label>
        </form>
        -->
        <!-- all the bugs are dumped the #issue-list after being retrieved and matched to the ones in the page -->
        <!--
        <div id="issue-list">

        </div>
    </div>
-->

<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-declaration:"~/SGML/HTML4.decl"
sgml-default-doctype-name:"html"
sgml-minimize-attributes:t
sgml-nofill-elements:("pre" "style" "br")
sgml-live-element-indicator:t
sgml-omittag:nil
sgml-shorttag:nil
sgml-namecase-general:t
sgml-general-insert-case:lower
sgml-always-quote-attributes:t
sgml-indent-step:nil
sgml-indent-data:t
sgml-parent-document:nil
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
-->
